Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditionally removing fields from introspection #1004

Closed
wants to merge 2 commits into from
Closed

Conditionally removing fields from introspection #1004

wants to merge 2 commits into from

Conversation

andcan
Copy link

@andcan andcan commented Feb 4, 2020

Fixes #380

How to use

Use introspection plugin with AllowFieldFunc and AllowInputValueFunc.

How it works

Introspection extension now implements FieldInterceptor.
When InterceptField is called checks if the result returned by next() is
[]introspection.Field or []introspection.InputValue.
If any of the two conditions is true proceeds to filter field using the correct AllowFunc specified when creating the extension.

I have:

  • Added tests covering the bug / feature (see testing)
  • Updated any relevant documentation (see docs)

@coveralls
Copy link

Coverage Status

Coverage increased (+0.1%) to 65.82% when pulling 223046a on andcan:introspection into e1f2282 on 99designs:master.

@andcan
Copy link
Author

andcan commented Feb 4, 2020

Still work in progress breaks if FieldContext.Parent.Result is not an *introspection.Type

if c.AllowInputValueFunc == nil {
return
}
t := fc.Parent.Result.(*introspection.Type)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

intropection.Type, intropection.Directive and introspection.Field will be coming.
https://spec.graphql.org/June2018/#sec-Schema-Introspection __InputValue

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking to change it to something like

type Introspection struct {
	Auth IntrospectionAuth
}

type IntrospectionAuth interface {
	AllowEnumValues(ctx context.Context, enumValues []introspection.EnumValue) ([]introspection.EnumValue, error)

	AllowFields(ctx context.Context, fields []introspection.Field) ([]introspection.Field, error)

	AllowInputValues(ctx context.Context, inputValues []introspection.InputValue) ([]introspection.InputValue, error)
}

and the allow func would be something like:

AllowFieldsFunc: func(ctx context.Context, fields []introspection.Field) ([]introspection.Field, error) {
						fc := graphql.GetFieldContext(ctx)
						newFields := make([]introspection.Field, 0, len(fields))
						if t, ok := fc.Parent.Result.(*introspection.Type); ok && *t.Name() == "TestType1" {
							for _, field := range fields {
								if field.Name == "TestField1" {
									continue
								}
								newFields = append(newFields, field)
							}
							return newFields, nil
						}
						return fields, nil
					},

This way the allow func is more verbose, but is called just one time and there is no need to have one function for each of intropection.Type, intropection.Directive and introspection.Field.
What do you think?

@andcan andcan closed this Mar 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Conditionally removing fields from introspection based on auth
3 participants